﻿#include "SelectScene.h"
#include "../MirSounds/SoundManager.h"
#include "../MirGraphics/MLibrary.h"
#include "../Settings.h"
#include "../MirControls/MirMessageBox.h"
#include "../../Shared/ClientPackets.h"
#include "../MirNetwork/Network.h"
#include "../Forms/Client.CMain.h"
#include "../../Shared/Globals.h"
#include "GameScene.h"

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirSounds;
namespace C = ClientPackets;
namespace S = ServerPackets;

namespace Client::MirScenes
{

    SelectScene::SelectScene(std::vector<SelectInfo*> &characters)
    {
        SoundManager::PlaySound(SoundList::SelectMusic, true);
        Disposing += [&] (o, e)
        {
            SoundManager::StopSound(SoundList::SelectMusic);
        };

        Characters = characters;
        SortList();

        KeyPress += SelectScene_KeyPress;

        Background = new MirImageControl();
        Background->setIndex(65);
        Background->setLibrary(Libraries::Prguse);
        Background->setParent(this);

        Title = new MirImageControl();
        Title->setIndex(40);
        Title->setLibrary(Libraries::Title);
        Title->setParent(this);
        Point tempVar(468, 20);
        Title->setLocation(&tempVar);

        ServerLabel = new MirLabel();
        Point tempVar2(432, 60);
        ServerLabel->setLocation(&tempVar2);
        ServerLabel->setParent(Background);
        Size tempVar3(155, 17);
        ServerLabel->setSize(&tempVar3);
        ServerLabel->setText("Legend of Mir 2");
        ServerLabel->setDrawFormat(TextFormatFlags::HorizontalCenter | TextFormatFlags::VerticalCenter);

        auto xPoint = ((Settings::ScreenWidth - 200) / 5);

        StartGameButton = new MirButton();
        StartGameButton->setEnabled(false);
        StartGameButton->setHoverIndex(341);
        StartGameButton->setIndex(340);
        StartGameButton->setLibrary(Libraries::Title);
        Point tempVar4(100 + (xPoint * 1) - (xPoint / 2) - 50, Settings::ScreenHeight - 32);
        StartGameButton->setLocation(&tempVar4);
        StartGameButton->setParent(Background);
        StartGameButton->setPressedIndex(342);
        StartGameButton->Click += [&] (o, e)
        {
            StartGame();
        };

        NewCharacterButton = new MirButton();
        NewCharacterButton->setHoverIndex(344);
        NewCharacterButton->setIndex(343);
        NewCharacterButton->setLibrary(Libraries::Title);
        Point tempVar5(100 + (xPoint * 2) - (xPoint / 2) - 50, Settings::ScreenHeight - 32);
        NewCharacterButton->setLocation(&tempVar5);
        NewCharacterButton->setParent(Background);
        NewCharacterButton->setPressedIndex(345);
        NewCharacterButton->Click += [&] (o, e)
        {
            _character = new NewCharacterDialog();
            _character->setParent(this);
        };

        DeleteCharacterButton = new MirButton();
        DeleteCharacterButton->setHoverIndex(347);
        DeleteCharacterButton->setIndex(346);
        DeleteCharacterButton->setLibrary(Libraries::Title);
        Point tempVar6(100 + (xPoint * 3) - (xPoint / 2) - 50, Settings::ScreenHeight - 32);
        DeleteCharacterButton->setLocation(&tempVar6);
        DeleteCharacterButton->setParent(Background);
        DeleteCharacterButton->setPressedIndex(348);
        DeleteCharacterButton->Click += [&] (o, e)
        {
            DeleteCharacter();
        };


        CreditsButton = new MirButton();
        CreditsButton->setHoverIndex(350);
        CreditsButton->setIndex(349);
        CreditsButton->setLibrary(Libraries::Title);
        Point tempVar7(100 + (xPoint * 4) - (xPoint / 2) - 50, Settings::ScreenHeight - 32);
        CreditsButton->setLocation(&tempVar7);
        CreditsButton->setParent(Background);
        CreditsButton->setPressedIndex(351);
        CreditsButton->Click += [&] (o, e)
        {
    
        };

        ExitGame = new MirButton();
        ExitGame->setHoverIndex(353);
        ExitGame->setIndex(352);
        ExitGame->setLibrary(Libraries::Title);
        Point tempVar8(100 + (xPoint * 5) - (xPoint / 2) - 50, Settings::ScreenHeight - 32);
        ExitGame->setLocation(&tempVar8);
        ExitGame->setParent(Background);
        ExitGame->setPressedIndex(354);
        ExitGame->Click += [&] (o, e)
        {
            Program::Form->Close();
        };


        CharacterDisplay = new MirAnimatedControl();
        CharacterDisplay->setAnimated(true);
        CharacterDisplay->setAnimationCount(16);
        CharacterDisplay->setAnimationDelay(250);
        CharacterDisplay->setFadeIn(true);
        CharacterDisplay->setFadeInDelay(75);
        CharacterDisplay->setFadeInRate(0.1F);
        CharacterDisplay->setIndex(220);
        CharacterDisplay->setLibrary(Libraries::ChrSel);
        Point tempVar9(260, 420);
        CharacterDisplay->setLocation(&tempVar9);
        CharacterDisplay->setParent(Background);
        CharacterDisplay->setUseOffSet(true);
        CharacterDisplay->setVisible(false);
        CharacterDisplay->AfterDraw += [&] (o, e)
        {
            // if (_selected >= 0 && _selected < Characters.Count && characters[_selected].Class == MirClass.Wizard)
            Libraries::ChrSel->DrawBlend(CharacterDisplay->getIndex() + 560, CharacterDisplay->getDisplayLocationWithoutOffSet(), Color::White, true);
        };

        CharacterButtons = std::vector<CharacterButton*>(4);

        CharacterButton *tempVar10 = new CharacterButton();
        Point tempVar11(637, 194);
        tempVar10->setLocation(&tempVar11);
        tempVar10->setParent(Background);
        tempVar10->setSound(SoundList::ButtonA);
        CharacterButtons[0] = tempVar10;
        CharacterButtons[0]->Click += [&] (o, e)
        {
            if (characters.size() <= 0)
            {
                return;
            }
    
            _selected = 0;
            UpdateInterface();
        };

        CharacterButton *tempVar12 = new CharacterButton();
        Point tempVar13(637, 298);
        tempVar12->setLocation(&tempVar13);
        tempVar12->setParent(Background);
        tempVar12->setSound(SoundList::ButtonA);
        CharacterButtons[1] = tempVar12;
        CharacterButtons[1]->Click += [&] (o, e)
        {
            if (characters.size() <= 1)
            {
                return;
            }
            _selected = 1;
            UpdateInterface();
        };

        CharacterButton *tempVar14 = new CharacterButton();
        Point tempVar15(637, 402);
        tempVar14->setLocation(&tempVar15);
        tempVar14->setParent(Background);
        tempVar14->setSound(SoundList::ButtonA);
        CharacterButtons[2] = tempVar14;
        CharacterButtons[2]->Click += [&] (o, e)
        {
            if (characters.size() <= 2)
            {
                return;
            }
    
            _selected = 2;
            UpdateInterface();
        };

        CharacterButton *tempVar16 = new CharacterButton();
        Point tempVar17(637, 506);
        tempVar16->setLocation(&tempVar17);
        tempVar16->setParent(Background);
        tempVar16->setSound(SoundList::ButtonA);
        CharacterButtons[3] = tempVar16;
        CharacterButtons[3]->Click += [&] (o, e)
        {
            if (characters.size() <= 3)
            {
                return;
            }
    
            _selected = 3;
            UpdateInterface();
        };

        LastAccessLabel = new MirLabel();
        Point tempVar18(265, 609);
        LastAccessLabel->setLocation(&tempVar18);
        LastAccessLabel->setParent(Background);
        Size tempVar19(180, 21);
        LastAccessLabel->setSize(&tempVar19);
        LastAccessLabel->setDrawFormat(TextFormatFlags->Left | TextFormatFlags::VerticalCenter);
        LastAccessLabel->setBorder(true);
        LastAccessLabelLabel = new MirLabel();
        Point tempVar20(-65, 0);
        LastAccessLabelLabel->setLocation(&tempVar20);
        LastAccessLabelLabel->setParent(LastAccessLabel);
        LastAccessLabelLabel->setText("Last Online:");
        Size tempVar21(100, 21);
        LastAccessLabelLabel->setSize(&tempVar21);
        LastAccessLabelLabel->setDrawFormat(TextFormatFlags->Left | TextFormatFlags::VerticalCenter);
        LastAccessLabelLabel->setBorder(true);
        UpdateInterface();

        delete tempVar16;
        delete tempVar14;
        delete tempVar12;
        delete tempVar10;
    }

    void SelectScene::SelectScene_KeyPress(std::any sender, KeyPressEventArgs *e)
    {
        if (e->KeyChar != static_cast<char>(Keys->Enter))
        {
            return;
        }
        if (StartGameButton->getEnabled())
        {
            StartGame();
        }
        e->Handled = true;
    }

    void SelectScene::SortList()
    {
        if (!Characters.empty())
        {
//C# TO C++ CONVERTER TODO TASK: The 'Compare' parameter of std::sort produces a boolean value, while the .NET Comparison parameter produces a tri-state result:
//ORIGINAL LINE: Characters.Sort((c1, c2) => c2.LastAccess.CompareTo(c1.LastAccess));
            std::sort(Characters.begin(), Characters.end(), [&] (c1, c2)
            {
                c2::LastAccess->CompareTo(c1::LastAccess);
            });
        }
    }

    void SelectScene::StartGame()
    {
        if (!Libraries::Loaded)
        {
            MirMessageBox *message = new MirMessageBox(std::string::Format("Please wait, The game is still loading... {0:##0}%", Libraries::Progress / static_cast<double>(Libraries::Count) * 100), MirMessageBoxButtons::Cancel);

            message->BeforeDraw += [&] (o, e)
            {
                message->Label->setText(std::string::Format("Please wait, The game is still loading... {0:##0}%", Libraries::Progress / static_cast<double>(Libraries::Count) * 100));
            };

            message->AfterDraw += [&] (o, e)
            {
                if (!Libraries::Loaded)
                {
                    return;
                }
                message->Dispose();
                StartGame();
            };

            message->Show();

            delete message;
            return;
        }
        StartGameButton->setEnabled(false);

        C::StartGame *tempVar = new C::StartGame();
        tempVar->CharacterIndex = Characters[_selected]->Index;
        Network::Enqueue(tempVar);

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
    }

    void SelectScene::Process()
    {


    }

    void SelectScene::ProcessPacket(Packet *p)
    {
        switch (p->getIndex())
        {
            case static_cast<short>(ServerPacketIds::NewCharacter):
                NewCharacter(static_cast<S::NewCharacter*>(p));
                break;
            case static_cast<short>(ServerPacketIds::NewCharacterSuccess):
                NewCharacter(static_cast<S::NewCharacterSuccess*>(p));
                break;
            case static_cast<short>(ServerPacketIds::DeleteCharacter):
                DeleteCharacter(static_cast<S::DeleteCharacter*>(p));
                break;
            case static_cast<short>(ServerPacketIds::DeleteCharacterSuccess):
                DeleteCharacter(static_cast<S::DeleteCharacterSuccess*>(p));
                break;
            case static_cast<short>(ServerPacketIds::StartGame):
                StartGame(static_cast<S::StartGame*>(p));
                break;
            case static_cast<short>(ServerPacketIds::StartGameBanned):
                StartGame(static_cast<S::StartGameBanned*>(p));
                break;
            case static_cast<short>(ServerPacketIds::StartGameDelay):
                StartGame(static_cast<S::StartGameDelay*>(p));
                break;
            default:
                MirScene::ProcessPacket(p);
                break;
        }
    }

    void SelectScene::NewCharacter(S::NewCharacter *p)
    {
        _character->OKButton->setEnabled(true);

        switch (p->Result)
        {
            case 0:
                MirMessageBox::Show("Creating new characters is currently disabled.");
                _character->Dispose();
                break;
            case 1:
                MirMessageBox::Show("Your Character Name is not acceptable.");
                _character->NameTextBox->SetFocus();
                break;
            case 2:
                MirMessageBox::Show("The gender you selected does not exist.\n Contact a GM for assistance.");
                break;
            case 3:
                MirMessageBox::Show("The class you selected does not exist.\n Contact a GM for assistance.");
                break;
            case 4:
                MirMessageBox::Show("You cannot make anymore then " + std::to_string(Globals::MaxCharacterCount) + " Characters.");
                _character->Dispose();
                break;
            case 5:
                MirMessageBox::Show("A Character with this name already exists.");
                _character->NameTextBox->SetFocus();
                break;
        }


    }

    void SelectScene::NewCharacter(S::NewCharacterSuccess *p)
    {
        _character->Dispose();
        MirMessageBox::Show("Your character was created successfully.");

        Characters.Insert(0, p->CharInfo);
        _selected = 0;
        UpdateInterface();
    }

    void SelectScene::DeleteCharacter()
    {
        if (_selected < 0 || _selected >= Characters.size())
        {
            return;
        }

        MirMessageBox *message = new MirMessageBox(StringHelper::formatSimple("Are you sure you want to Delete the character {0}?", Characters[_selected]->Name), MirMessageBoxButtons::YesNo);
        int index = Characters[_selected]->Index;

        message->YesButton->Click += [&] (o, e)
        {
            DeleteCharacterButton->setEnabled(false);
            C::DeleteCharacter *tempVar = new C::DeleteCharacter();
            tempVar->CharacterIndex = index;
            Network::Enqueue(tempVar);

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
        };

        message->Show();

        delete message;
    }

    void SelectScene::DeleteCharacter(S::DeleteCharacter *p)
    {
        DeleteCharacterButton->setEnabled(true);
        switch (p->Result)
        {
            case 0:
                MirMessageBox::Show("Deleting characters is currently disabled.");
                break;
            case 1:
                MirMessageBox::Show("The character you selected does not exist.\n Contact a GM for assistance.");
                break;
        }
    }

    void SelectScene::DeleteCharacter(S::DeleteCharacterSuccess *p)
    {
        DeleteCharacterButton->setEnabled(true);
        MirMessageBox::Show("Your character was deleted successfully.");

        for (int i = 0; i < Characters.size(); i++)
        {
            if (Characters[i]->Index == p->CharacterIndex)
            {
                Characters.erase(Characters.begin() + i);
                break;
            }
        }

        UpdateInterface();
    }

    void SelectScene::StartGame(S::StartGameDelay *p)
    {
        StartGameButton->setEnabled(true);

        long long time = CMain::Time + p->Milliseconds;

        MirMessageBox *message = new MirMessageBox(StringHelper::formatSimple("You cannot log onto this character for another {0} seconds.", std::ceil(p->Milliseconds / 1000)));

        message->BeforeDraw += [&] (o, e)
        {
            message->Label->setText(StringHelper::formatSimple("You cannot log onto this character for another {0} seconds.", std::ceil((time - CMain::Time) / 1000)));
        };


        message->AfterDraw += [&] (o, e)
        {
            if (CMain::Time <= time)
            {
                return;
            }
            message->Dispose();
            StartGame();
        };

        message->Show();

        delete message;
    }

    void SelectScene::StartGame(S::StartGameBanned *p)
    {
        StartGameButton->setEnabled(true);

        TimeSpan d = p->ExpiryDate - CMain::getNow();
        MirMessageBox::Show(std::string::Format("This account is banned.\n\nReason: {0}\nExpiryDate: {1}\nDuration: {2:#,##0} Hours, {3} Minutes, {4} Seconds", p->Reason, p->ExpiryDate, std::floor(d.TotalHours), d.Minutes, d.Seconds));
    }

    void SelectScene::StartGame(S::StartGame *p)
    {
        StartGameButton->setEnabled(true);

        switch (p->Result)
        {
            case 0:
                MirMessageBox::Show("Starting the game is currently disabled.");
                break;
            case 1:
                MirMessageBox::Show("You are not logged in.");
                break;
            case 2:
                MirMessageBox::Show("Your character could not be found.");
                break;
            case 3:
                MirMessageBox::Show("No active map and/or start point found.");
                break;
            case 4:

                if (p->Resolution < Settings::Resolution || Settings::Resolution == 0)
                {
                    Settings::Resolution = p->Resolution;
                }

                switch (Settings::Resolution)
                {
                    default:
                    case 1024:
                        Settings::Resolution = 1024;
                        CMain::SetResolution(1024, 768);
                        break;
                    case 1280:
                        CMain::SetResolution(1280, 800);
                        break;
                    case 1366:
                        CMain::SetResolution(1366, 768);
                        break;
                    case 1920:
                        CMain::SetResolution(1920, 1080);
                        break;
                }

                ActiveScene = new GameScene();
                Dispose();
                break;
        }
    }

    void SelectScene::UpdateInterface()
    {
        for (int i = 0; i < CharacterButtons.size(); i++)
        {
            CharacterButtons[i]->Selected = i == _selected;
            CharacterButtons[i]->Update(i >= Characters.size() ? nullptr : Characters[i]);
        }

        if (_selected >= 0 && _selected < Characters.size())
        {
            CharacterDisplay->setVisible(true);
            //CharacterDisplay.Index = ((byte)Characters[_selected].Class + 1) * 20 + (byte)Characters[_selected].Gender * 280; 

            switch (static_cast<MirClass>(Characters[_selected]->Class))
            {
                case MirClass::Warrior:
                    CharacterDisplay->setIndex(static_cast<unsigned char>(Characters[_selected]->Gender) == 0 ? 20 : 300); //220 : 500;
                    break;
                case MirClass::Wizard:
                    CharacterDisplay->setIndex(static_cast<unsigned char>(Characters[_selected]->Gender) == 0 ? 40 : 320); //240 : 520;
                    break;
                case MirClass::Taoist:
                    CharacterDisplay->setIndex(static_cast<unsigned char>(Characters[_selected]->Gender) == 0 ? 60 : 340); //260 : 540;
                    break;
                case MirClass::Assassin:
                    CharacterDisplay->setIndex(static_cast<unsigned char>(Characters[_selected]->Gender) == 0 ? 80 : 360); //280 : 560;
                    break;
                case MirClass::Archer:
                    CharacterDisplay->setIndex(static_cast<unsigned char>(Characters[_selected]->Gender) == 0 ? 100 : 140); //160 : 180;
                    break;
            }

//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
            LastAccessLabel->setText(Characters[_selected]->LastAccess == DateTime::MinValue ? "Never" : Characters[_selected]->LastAccess.ToString());
            LastAccessLabel->setVisible(true);
            LastAccessLabelLabel->setVisible(true);
            StartGameButton->setEnabled(true);
        }
        else
        {
            CharacterDisplay->setVisible(false);
            LastAccessLabel->setVisible(false);
            LastAccessLabelLabel->setVisible(false);
            StartGameButton->setEnabled(false);
        }
    }

    void SelectScene::Dispose(bool disposing)
    {
        if (disposing)
        {
            Background = nullptr;
            _character = nullptr;

            ServerLabel = nullptr;
            CharacterDisplay = nullptr;
            StartGameButton = nullptr;
            NewCharacterButton = nullptr;
            DeleteCharacterButton = nullptr;
            CreditsButton = nullptr;
            ExitGame = nullptr;
            CharacterButtons = std::vector<CharacterButton*>();
            LastAccessLabel = nullptr;
            LastAccessLabelLabel = nullptr;
            Characters = std::vector<SelectInfo*>();
            _selected = 0;
        }

        MirScene::Dispose(disposing);
    }

Regex *const SelectScene::NewCharacterDialog::Reg = new Regex(R"(^[A-Za-z0-9]{)" + std::to_string(Globals::MinCharacterNameLength) + "," + std::to_string(Globals::MaxCharacterNameLength) + "}$");
const std::string SelectScene::NewCharacterDialog::WarriorDescription = "Warriors are a class of great strength and vitality. They are not easily killed in battle and have the advantage of being able to use" + " a variety of heavy weapons and Armour. Therefore, Warriors favor attacks that are based on melee physical damage. They are weak in ranged" + " attacks, however the variety of equipment that are developed specifically for Warriors complement their weakness in ranged combat.";
const std::string SelectScene::NewCharacterDialog::WizardDescription = "Wizards are a class of low strength and stamina, but have the ability to use powerful spells. Their offensive spells are very effective, but" + " because it takes time to cast these spells, they're likely to leave themselves open for enemy's attacks. Therefore, the physically weak wizards" + " must aim to attack their enemies from a safe distance.";
const std::string SelectScene::NewCharacterDialog::TaoistDescription = "Taoists are well disciplined in the study of Astronomy, Medicine, and others aside from Mu-Gong. Rather then directly engaging the enemies, their" + " specialty lies in assisting their allies with support. Taoists can summon powerful creatures and have a high resistance to magic, and is a class" + " with well balanced offensive and defensive abilities.";
const std::string SelectScene::NewCharacterDialog::AssassinDescription = "Assassins are members of a secret organization and their history is relatively unknown. They're capable of hiding themselves and performing attacks" + " while being unseen by others, which naturally makes them excellent at making fast kills. It is necessary for them to avoid being in battles with" + " multiple enemies due to their weak vitality and strength.";
const std::string SelectScene::NewCharacterDialog::ArcherDescription = "Archers are a class of great accuracy and strength, using their powerful skills with bows to deal extraordinary damage from range. Much like" + " wizards, they rely on their keen instincts to dodge oncoming attacks as they tend to leave themselves open to frontal attacks. However, their" + " physical prowess and deadly aim allows them to instil fear into anyone they hit.";

    SelectScene::NewCharacterDialog::NewCharacterDialog()
    {
        setIndex(73);
        setLibrary(Libraries::Prguse);
        Point tempVar((Settings::ScreenWidth - getSize()->Width) / 2, (Settings::ScreenHeight - getSize()->Height) / 2);
        setLocation(&tempVar);
        setModal(true);

        TitleLabel = new MirImageControl();
        TitleLabel->setIndex(20);
        TitleLabel->setLibrary(Libraries::Title);
        Point tempVar2(206, 11);
        TitleLabel->setLocation(&tempVar2);
        TitleLabel->setParent(this);

        CancelButton = new MirButton();
        CancelButton->setHoverIndex(281);
        CancelButton->setIndex(280);
        CancelButton->setLibrary(Libraries::Title);
        Point tempVar3(425, 425);
        CancelButton->setLocation(&tempVar3);
        CancelButton->setParent(this);
        CancelButton->setPressedIndex(282);
        CancelButton->Click += [&] (o, e)
        {
            Dispose();
        };


        OKButton = new MirButton();
        OKButton->setEnabled(false);
        OKButton->setHoverIndex(361);
        OKButton->setIndex(360);
        OKButton->setLibrary(Libraries::Title);
        Point tempVar4(160, 425);
        OKButton->setLocation(&tempVar4);
        OKButton->setParent(this);
        OKButton->setPressedIndex(362);
        OKButton->Click += [&] (o, e)
        {
            CreateCharacter();
        };

        NameTextBox = new MirTextBox();
        Point tempVar5(325, 268);
        NameTextBox->setLocation(&tempVar5);
        NameTextBox->setParent(this);
        Size tempVar6(240, 20);
        NameTextBox->setSize(&tempVar6);
        NameTextBox->setMaxLength(Globals::MaxCharacterNameLength);
        NameTextBox->TextBox->KeyPress += TextBox_KeyPress;
        NameTextBox->TextBox->TextChanged += CharacterNameTextBox_TextChanged;
        NameTextBox->SetFocus();

        CharacterDisplay = new MirAnimatedControl();
        CharacterDisplay->setAnimated(true);
        CharacterDisplay->setAnimationCount(16);
        CharacterDisplay->setAnimationDelay(250);
        CharacterDisplay->setIndex(20);
        CharacterDisplay->setLibrary(Libraries::ChrSel);
        Point tempVar7(120, 250);
        CharacterDisplay->setLocation(&tempVar7);
        CharacterDisplay->setParent(this);
        CharacterDisplay->setUseOffSet(true);
        CharacterDisplay->AfterDraw += [&] (o, e)
        {
            if (_class == MirClass::Wizard)
            {
                Libraries::ChrSel->DrawBlend(CharacterDisplay->getIndex() + 560, CharacterDisplay->getDisplayLocationWithoutOffSet(), Color::White, true);
            }
        };


        WarriorButton = new MirButton();
        WarriorButton->setHoverIndex(2427);
        WarriorButton->setIndex(2427);
        WarriorButton->setLibrary(Libraries::Prguse);
        Point tempVar8(323, 296);
        WarriorButton->setLocation(&tempVar8);
        WarriorButton->setParent(this);
        WarriorButton->setPressedIndex(2428);
        WarriorButton->setSound(SoundList::ButtonA);
        WarriorButton->Click += [&] (o, e)
        {
            _class = MirClass::Warrior;
            UpdateInterface();
        };


        WizardButton = new MirButton();
        WizardButton->setHoverIndex(2430);
        WizardButton->setIndex(2429);
        WizardButton->setLibrary(Libraries::Prguse);
        Point tempVar9(373, 296);
        WizardButton->setLocation(&tempVar9);
        WizardButton->setParent(this);
        WizardButton->setPressedIndex(2431);
        WizardButton->setSound(SoundList::ButtonA);
        WizardButton->Click += [&] (o, e)
        {
            _class = MirClass::Wizard;
            UpdateInterface();
        };


        TaoistButton = new MirButton();
        TaoistButton->setHoverIndex(2433);
        TaoistButton->setIndex(2432);
        TaoistButton->setLibrary(Libraries::Prguse);
        Point tempVar10(423, 296);
        TaoistButton->setLocation(&tempVar10);
        TaoistButton->setParent(this);
        TaoistButton->setPressedIndex(2434);
        TaoistButton->setSound(SoundList::ButtonA);
        TaoistButton->Click += [&] (o, e)
        {
            _class = MirClass::Taoist;
            UpdateInterface();
        };

        AssassinButton = new MirButton();
        AssassinButton->setHoverIndex(2436);
        AssassinButton->setIndex(2435);
        AssassinButton->setLibrary(Libraries::Prguse);
        Point tempVar11(473, 296);
        AssassinButton->setLocation(&tempVar11);
        AssassinButton->setParent(this);
        AssassinButton->setPressedIndex(2437);
        AssassinButton->setSound(SoundList::ButtonA);
        AssassinButton->Click += [&] (o, e)
        {
            _class = MirClass::Assassin;
            UpdateInterface();
        };

        ArcherButton = new MirButton();
        ArcherButton->setHoverIndex(2439);
        ArcherButton->setIndex(2438);
        ArcherButton->setLibrary(Libraries::Prguse);
        Point tempVar12(523, 296);
        ArcherButton->setLocation(&tempVar12);
        ArcherButton->setParent(this);
        ArcherButton->setPressedIndex(2440);
        ArcherButton->setSound(SoundList::ButtonA);
        ArcherButton->Click += [&] (o, e)
        {
            _class = MirClass::Archer;
            UpdateInterface();
        };


        MaleButton = new MirButton();
        MaleButton->setHoverIndex(2421);
        MaleButton->setIndex(2421);
        MaleButton->setLibrary(Libraries::Prguse);
        Point tempVar13(323, 343);
        MaleButton->setLocation(&tempVar13);
        MaleButton->setParent(this);
        MaleButton->setPressedIndex(2422);
        MaleButton->setSound(SoundList::ButtonA);
        MaleButton->Click += [&] (o, e)
        {
            _gender = MirGender::Male;
            UpdateInterface();
        };

        FemaleButton = new MirButton();
        FemaleButton->setHoverIndex(2424);
        FemaleButton->setIndex(2423);
        FemaleButton->setLibrary(Libraries::Prguse);
        Point tempVar14(373, 343);
        FemaleButton->setLocation(&tempVar14);
        FemaleButton->setParent(this);
        FemaleButton->setPressedIndex(2425);
        FemaleButton->setSound(SoundList::ButtonA);
        FemaleButton->Click += [&] (o, e)
        {
            _gender = MirGender::Female;
            UpdateInterface();
        };

        Description = new MirLabel();
        Description->setBorder(true);
        Point tempVar15(279, 70);
        Description->setLocation(&tempVar15);
        Description->setParent(this);
        Size tempVar16(278, 170);
        Description->setSize(&tempVar16);
        Description->setText(WarriorDescription);
    }

    void SelectScene::NewCharacterDialog::TextBox_KeyPress(std::any sender, KeyPressEventArgs *e)
    {
        if (!sender.has_value())
        {
            return;
        }
        if (e->KeyChar != static_cast<char>(Keys->Enter))
        {
            return;
        }
        e->Handled = true;

        if (OKButton->getEnabled())
        {
            OKButton->InvokeMouseClick(nullptr);
        }
    }

    void SelectScene::NewCharacterDialog::CharacterNameTextBox_TextChanged(std::any sender, EventArgs *e)
    {
        if (NameTextBox->getText().empty())
        {
            OKButton->setEnabled(false);
            NameTextBox->setBorder(false);
        }
        else if (!Reg->IsMatch(NameTextBox->getText()))
        {
            OKButton->setEnabled(false);
            NameTextBox->setBorder(true);
            NameTextBox->setBorderColour(Color::Red);
        }
        else
        {
            OKButton->setEnabled(true);
            NameTextBox->setBorder(true);
            NameTextBox->setBorderColour(Color::Green);
        }
    }

    void SelectScene::NewCharacterDialog::CreateCharacter()
    {
        OKButton->setEnabled(false);

        C::NewCharacter *tempVar = new C::NewCharacter();
        tempVar->Name = NameTextBox->getText();
        tempVar->Class = _class;
        tempVar->Gender = _gender;
        Network::Enqueue(tempVar);

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
    }

    void SelectScene::NewCharacterDialog::UpdateInterface()
    {
        MaleButton->setIndex(2420);
        FemaleButton->setIndex(2423);

        WarriorButton->setIndex(2426);
        WizardButton->setIndex(2429);
        TaoistButton->setIndex(2432);
        AssassinButton->setIndex(2435);
        ArcherButton->setIndex(2438);

        switch (_gender)
        {
            case MirGender::Male:
                MaleButton->setIndex(2421);
                break;
            case MirGender::Female:
                FemaleButton->setIndex(2424);
                break;
        }

        switch (_class)
        {
            case MirClass::Warrior:
                WarriorButton->setIndex(2427);
                Description->setText(WarriorDescription);
                CharacterDisplay->setIndex(static_cast<unsigned char>(_gender) == 0 ? 20 : 300); //220 : 500;
                break;
            case MirClass::Wizard:
                WizardButton->setIndex(2430);
                Description->setText(WizardDescription);
                CharacterDisplay->setIndex(static_cast<unsigned char>(_gender) == 0 ? 40 : 320); //240 : 520;
                break;
            case MirClass::Taoist:
                TaoistButton->setIndex(2433);
                Description->setText(TaoistDescription);
                CharacterDisplay->setIndex(static_cast<unsigned char>(_gender) == 0 ? 60 : 340); //260 : 540;
                break;
            case MirClass::Assassin:
                AssassinButton->setIndex(2436);
                Description->setText(AssassinDescription);
                CharacterDisplay->setIndex(static_cast<unsigned char>(_gender) == 0 ? 80 : 360); //280 : 560;
                break;
            case MirClass::Archer:
                ArcherButton->setIndex(2439);
                Description->setText(ArcherDescription);
                CharacterDisplay->setIndex(static_cast<unsigned char>(_gender) == 0 ? 100 : 140); //160 : 180;
                break;
        }

        //CharacterDisplay.Index = ((byte)_class + 1) * 20 + (byte)_gender * 280;
    }

    SelectScene::CharacterButton::CharacterButton()
    {
        setIndex(44); //45 locked
        setLibrary(Libraries::Prguse);
        setSound(SoundList::ButtonA);

        NameLabel = new MirLabel();
        Point tempVar(107, 9);
        NameLabel->setLocation(&tempVar);
        NameLabel->setParent(this);
        NameLabel->setNotControl(true);
        Size tempVar2(170, 18);
        NameLabel->setSize(&tempVar2);

        LevelLabel = new MirLabel();
        Point tempVar3(107, 28);
        LevelLabel->setLocation(&tempVar3);
        LevelLabel->setParent(this);
        LevelLabel->setNotControl(true);
        Size tempVar4(30, 18);
        LevelLabel->setSize(&tempVar4);

        ClassLabel = new MirLabel();
        Point tempVar5(178, 28);
        ClassLabel->setLocation(&tempVar5);
        ClassLabel->setParent(this);
        ClassLabel->setNotControl(true);
        Size tempVar6(100, 18);
        ClassLabel->setSize(&tempVar6);
    }

    void SelectScene::CharacterButton::Update(SelectInfo *info)
    {
        if (info == nullptr)
        {
            setIndex(44);
            setLibrary(Libraries::Prguse);
            NameLabel->setText("");
            LevelLabel->setText("");
            ClassLabel->setText("");

            NameLabel->setVisible(false);
            LevelLabel->setVisible(false);
            ClassLabel->setVisible(false);

            return;
        }

        setLibrary(Libraries::Title);

        setIndex(660 + static_cast<unsigned char>(info->Class));

        if (Selected)
        {
            setIndex(getIndex() + 5);
        }


        NameLabel->setText(info->Name);
        LevelLabel->setText(std::to_string(info->Level));
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
        ClassLabel->setText(info->Class.ToString());

        NameLabel->setVisible(true);
        LevelLabel->setVisible(true);
        ClassLabel->setVisible(true);
    }
}
